//构建工具类
function f1(params) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("🚀 ~ setTimeout ~ f1bacyi:f1")
      reject(1)
    }, 1000)
  })
}
function f2(params) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("🚀 ~ setTimeout ~ 'f2':", 'f2')
      resolve('f2')
    }, 2000)
  })
}
function f3(params) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("🚀 ~ setTimeout ~ 'f3':", 'f3')
      resolve('f3')
    }, 3000)
  })
}
// class RequestList {
//   map = {}
//   list = []
//   success = []
//   error = []
//   constructor(fnlist, reTryNum = 3) {
//     this.list = fnlist
//     fnlist.forEach((fn, index) => {
//       let _id = "id_" + index;
//       //用id和方法，映射进map
//       this.map[_id] = fn;
//       // 把id给到方法的静态属性
//       fn.id = _id;
//       fn.hasTry = 0;
//       fn.reTry = reTryNum
//     })
//   }

//   createPromise(fn){
//     return new Promise((resolve, reject)=>{
//       fn().then((res)=>{
//         resolve({
//           id: fn.id,
//           value: res
//         })
//       }).catch(err => {
//         reject({
//           id: fn.id,
//           value: err
//         })
//       })
//     })
//   }

//   send(){
//     return new Promise((resolve, reject) => {
//       // 待请求队列
//       let _que = [];
//       //应为到时候失败了得再次调用a1lsetled重发，所以重发
//       this.list.forEach((fn)=>{
//         _que.push(this.createPromise(fn))
//       })
//       const sendAllSettled = () => {
//         Promise.allSettled(_que).then((res)=> {
//           // 发送完后,先清空
//           _que = []
//           res.forEach((singres => {
//             if(singres.status === 'fulfilled') {
//               this.success.push(singres.value)
//             } else {
//               // 如果失败,找出id
//               let _id = singres.reason.id
//               let _fn = this.map[_id]
//               // 是否超出最大值
//               if(_fn.hasTry < _fn.reTry) {
//                 // 如果出错了.再加入待请求队列,再次发送
//                 _que.push(this.createPromise(_fn))
//                 _fn.hasTry+=1
//               } else {
//                 this.error.push(singres.reason.value)
//               }
//             }
//           }))
//           if(_que.length === 0) {
//             resolve({
//               success: this.success,
//               error: this.error
//             })
//           } else {
//             sendAllSettled()
//           }
//           console.log("🚀 ~ RequestList ~ Promise.allSettled ~ res:", res)
//         }).catch(err => {
//           console.log("🚀 ~ RequestList ~ Promise.allSettled ~ err:", err)
//         })
//       }
//       sendAllSettled()

//     })
//   }
// }

// new RequestList([f1, f2, f3]).send().then(res => {
//   console.log("🚀 ~ newRequestList ~ res:最终结果", res)
// })





class ConcurrentRequestManager {  
  constructor(maxConcurrent, retryOptions = { retries: 0, delay: 0 }) {  
    this.maxConcurrent = maxConcurrent;  
    this.retryOptions = retryOptions;  
    this.activeCount = 0;  
    this.queue = [];  
    this.results = [];  
    this.errors = [];  
  }  
  
  // 发送请求的函数，需要由子类实现  
  sendRequest(requestData) {  
    throw new Error('sendRequest must be implemented by a subclass');  
  }  
  
  // 将请求添加到队列并处理  
  enqueue(requestData) {  
    const { retries, delay } = this.retryOptions;  
    const retryAttempt = {  
      id: requestData.id || Date.now(),  
      originalData: requestData,  
      hasTried: 0,  
      promise: null  
    };  
  
    // 封装重试逻辑的函数  
    const makeRequest = () => {  
      return new Promise((resolve, reject) => {  
        this.activeCount++;  
  
        const attemptRequest = () => {  
          this.sendRequest(retryAttempt.originalData)  
            .then(result => {  
              this.results.push({ id: retryAttempt.id, value: result });  
              resolve(result);  
            })  
            .catch(error => {  
              if (retryAttempt.hasTried < retries) {  
                retryAttempt.hasTried++;  
                setTimeout(() => {  
                  attemptRequest(); // 递归重试  
                }, delay);  
              } else {  
                this.errors.push({ id: retryAttempt.id, error: error });  
                reject(error);  
              }  
            })  
            .finally(() => {  
              this.activeCount--;  
              if (this.queue.length > 0 && this.activeCount < this.maxConcurrent) {  
                this.dequeue();  
              }  
            });  
        };  
  
        attemptRequest();  
      });  
    };  
  
    retryAttempt.promise = makeRequest();  
    this.queue.push(retryAttempt);  
  
    if (this.activeCount < this.maxConcurrent) {  
      this.dequeue();  
    }  
  }  
  
  // 从队列中取出请求并执行（如果未达到并发限制）  
  dequeue() {  
    if (this.queue.length > 0 && this.activeCount < this.maxConcurrent) {  
      const nextRequest = this.queue[0];  
      if (!nextRequest.promise) {  
        // 如果promise还未被创建（即第一次处理），则创建它  
        this.enqueue(nextRequest.originalData); // 注意：这里实际上不会再次入队，因为promise现在会被创建  
      }  
      // 注意：我们不需要显式地“取出”请求，因为promise的创建和执行会处理这一切  
      // 队列中的顺序和活跃计数会自动管理  
    }  
    // 但实际上，dequeue在这里可能不是必需的，因为enqueue已经处理了所有逻辑  
  }  
  
  // 等待所有请求完成（可选的便利方法）  
  waitForAll() {  
    return Promise.all(this.queue.map(item => item.promise));  
  }  
}  
  
// 示例子类  
class FetchRequestManager extends ConcurrentRequestManager {  
  sendRequest(requestData) {  
    // 模拟fetch请求  
    return new Promise((resolve, reject) => {  
      const isFailure = Math.random() > 0.5;  
      setTimeout(() => {  
        if (isFailure) {  
          reject(new Error(`Request for ${requestData.id} failed`));  
        } else {  
          resolve(`Success for ${requestData.id}`);  
        }  
      }, 500);  
    });  
  }  
}  
  
// 使用示例  
const manager = new FetchRequestManager(2, { retries: 2, delay: 1000 });  
console.log("🚀 ~ manager:", manager)
manager.enqueue({ id: 1 });  
manager.enqueue({ id: 2 });  
manager.enqueue({ id: 3 })

export {
  f1,
  f2,
  f3,
  // RequestList
}